package com.zsl.shop_book;

import com.alibaba.fastjson.JSON;
import com.zsl.shop_book.annotation.RequestMapping;
import com.zsl.shop_book.annotation.Response;
import com.zsl.shop_book.enums.RequestMethod;
import com.zsl.shop_book.method.HandlerMapping;
import com.zsl.shop_book.method.MVCMapping;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Map;

public class LoadServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        String path=config.getInitParameter("peizhi");
        InputStream is=LoadServlet.class.getResourceAsStream("/"+path);
        HandlerMapping handlerMapping=new HandlerMapping();
        handlerMapping.load(is);
    }
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String url=req.getRequestURI();
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        if(HandlerMapping.getUrlMap(url)!=null){
            //根据url得到MVCMapping
            MVCMapping mvcMapping= HandlerMapping.getUrlMap(url);
            if(type(req,resp,mvcMapping.method)){
                Object[] args=setParameters(req,resp,mvcMapping.method);
                Object result=null;
                try {
                    result=mvcMapping.method.invoke(mvcMapping.bean,args);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                String s=null;
                if(result instanceof String){
                    try {
                        s=(String)result;
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
                switch (mvcMapping.requestType){
                    case TEXT :
                        System.out.println(JSON.toJSONString(result));
                        resp.setHeader("content-type","text/json;charset=utf-8");
                        resp.getWriter().write(JSON.toJSONString(result));
                        break;
                    case VIEW:
                        if(s!=null){
                            if(s.startsWith("send:")){
                                resp.sendRedirect(s.substring(s.indexOf(":")+1));
                            }else {
                                req.getRequestDispatcher(s).forward(req,resp);
                            }
                        }else {
                            resp.sendError(666,"类型错误");
                        }
                }
            }
        }


    }
    private  boolean type(HttpServletRequest req, HttpServletResponse resp, Method method){
        String methodtype=req.getMethod();
        if(method.getAnnotation(RequestMapping.class)!=null){
            RequestMapping  requestMapping=method.getAnnotation(RequestMapping.class);
            if(requestMapping.method().length==0){
                return  true;
            }
            for (RequestMethod request:requestMapping.method()){
                if(request.toString().equals(methodtype)){
                    return  true;
                }
            }
            try {
                resp.sendError(444,"类型错误");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }else {
            Response response=method.getAnnotation(Response.class);
            if(response.method().length==0){
                return  true;
            }
            for (RequestMethod request:response.method()){
                if(request.toString().equals(methodtype)){
                    return  true;
                }
            }
            try {
                resp.sendError(444,"类型错误");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
    }

    private Object[] setParameters(HttpServletRequest req, HttpServletResponse resp, Method method){
        Parameter[] parameters=method.getParameters();
        Map<String,String[]> pMap=req.getParameterMap();
        Object[] args=new Object[parameters.length];
        for (int i=0;i<args.length;i++){
                System.out.println(parameters[i].getName());
                if(parameters[i].getType()==HttpServletRequest.class){
                    args[i]=req;
                }else if (parameters[i].getType()==HttpServletResponse.class){
                    args[i]=resp;
                }else if(parameters[i].getType()==String[].class){
                    args[i]=pMap.get(parameters[i].getName());
                }else if (parameters[i].getType() == String.class) {
                    args[i]=pMap.get(parameters[i].getName())[0];
                } else if (parameters[i].getType()== Integer.class || parameters[i].getType() == int.class) {
                    args[i]=Integer.parseInt(pMap.get(parameters[i].getName())[0]);
                } else if (parameters[i].getType() == Double.class || parameters[i].getType()  == double.class) {
                    args[i]=Double.parseDouble(pMap.get(parameters[i].getName())[0]);
                } else if (parameters[i].getType() == Float.class || parameters[i].getType() == float.class) {
                    args[i]=Float.parseFloat(pMap.get(parameters[i].getName())[0]);
                } else if (parameters[i].getType() == Long.class ||parameters[i].getType() == long.class) {
                    args[i]=Long.parseLong(pMap.get(parameters[i].getName())[0]);
                } else if (parameters[i].getType() == Byte.class || parameters[i].getType() == byte.class) {
                    args[i]=Byte.parseByte(pMap.get(parameters[i].getName())[0]);
                } else if (parameters[i].getType() == Short.class || parameters[i].getType()== short.class) {
                    args[i]=Short.parseShort(pMap.get(parameters[i].getName())[0]);
                } else if (parameters[i].getType() == Character.class || parameters[i].getType()== char.class) {
                    args[i]=(pMap.get(parameters[i].getName())[0]).toCharArray()[0];
                } else {
                    try {
                        resp.sendError(666,"暂不支持该类型");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        return args;
    }
}
